home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Telnet / NCSA / tn3270 2.3d26 source / tn3270 / hndkbd.c < prev    next >
Text File  |  1991-06-03  |  21KB  |  1,011 lines

  1. /*
  2.  *  tn3270 for the Macintosh Source Code
  3.  *  Brown University Computing and Information Services
  4.  *  Version 2.3d21, January 17, 1991
  5.  *  Copyright (c) 1988, 1989, 1990, 1991 by Brown University and by
  6.  *  Peter John DiCamillo.
  7.  *
  8.  *  Permission is granted to any individual or institution to use, copy,
  9.  *  or redistribute the binary version of this software and its
  10.  *  documentation provided this notice and the copyright notices are
  11.  *  retained.  Permission is granted to any individual or non-profit
  12.  *  institution to use, copy, modify, or redistribute the source files
  13.  *  of this software provided this notice and the copyright notices are
  14.  *  retained.  This software may not be distributed for profit, either
  15.  *  in original form or in derivative works, nor can the source be
  16.  *  distributed to other than an individual or a non-profit institution.
  17.  *  Any  individual or group interested in seeing and/or using these
  18.  *  source files but who are prevented from doing so by the above
  19.  *  constraints should contact Don Wolfe, Assistant Vice-President for
  20.  *  Computer Systems at Brown University, (401) 863-7250, for possible
  21.  *  software licensing of the source developed at Brown.
  22.  *
  23.  *  Brown University and Peter John DiCamillo make no representations
  24.  *  about the suitability of this software for any purpose.
  25.  *
  26.  *  BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
  27.  *  EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
  28.  *  INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
  29.  *  WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
  30.  *
  31.  */
  32.  
  33. #define __SEG__ 3270seg2
  34. #include "maclib.h"
  35. #include "termdef.h"
  36. #include "globals.h"
  37.  
  38. #define    IAC    255        /* interpret as command: */
  39. #define EOR 239     /* end of record (transparent mode) */
  40.  
  41. static char inschar = 0;
  42. extern short maxcnt, maxoff, scrhsize;
  43. extern char pend_conn;
  44. short cinsert();
  45. short getattr();
  46. short firstattr();
  47.  
  48. hndkbd(chr, shift)
  49. unsigned char chr, shift;
  50. {
  51. register unsigned char c;
  52. register unsigned char typ, val, geflag, alphaflag;
  53.  
  54. c = chr;                /* get character */
  55.  
  56.             /* define type, value, and geflag for key */
  57. typ = kbtyp[c];
  58. alphaflag = geflag = 0;
  59. if (typ & 0x80) geflag = 1;
  60. if (typ & 0x40) alphaflag = 1;
  61. typ &= 0x3f;
  62. if (aplmode) val = kbapl[c];
  63.     else {
  64.         val = kbstd[c];
  65.         if ((val == 0xad) || (val == 0xbd)) geflag = 1;
  66.         else geflag = 0;
  67.         }
  68.  
  69.             /* check if key should be ignored */
  70. if (val == 0) return;
  71.  
  72.              /* check if alpa lock needs to be applied */
  73. if (alphaflag && shift) val += 0x40;
  74.  
  75.             /* process key based on type code */
  76.  
  77. switch(typ) {
  78.     case 1: datakey(val, geflag);
  79.         break;
  80.  
  81.     case 2: attnkey(val);
  82.         break;
  83.  
  84.     case 3: funckey(val);
  85.         break;
  86.  
  87.     default: break;
  88.     }
  89. }
  90.  
  91. datakey(val, geflag)
  92. unsigned char val, geflag;
  93. {
  94. register short attroff;
  95. register short newattr;
  96. register short i;
  97. register unsigned char inpskip;
  98.  
  99. if (!fmtscrn) {                /* unformatted screen */
  100.     if (insmode || inschar) if (cinsert()) {  /* if insert, make room */
  101.             kerr(1);
  102.             beep();        /* error if no room */
  103.             apikberr = sendInsErr;
  104.             return;
  105.             }
  106.     newattr = atrbuff[curadr] & 0xbf00;
  107.     if (geflag) newattr |= 0x4000;
  108.     newchar(curadr, val, newattr, 0);
  109.     newwrite(0);
  110.     curadr++;
  111.     if (curadr == maxcnt) curadr = 0;
  112.     newcur();
  113.     kerr(0);
  114.     return;
  115.     }
  116.                     /* else formatted screen */
  117. if (atrbuff[curadr] & 0x8000) {        /* cursor on attribute byte */
  118.     kerr(2);
  119.     beep();
  120.     apikberr = sendAttrErr;
  121.     return;
  122.     }
  123. attroff = getattr(curadr);
  124. if (atrbuff[attroff] & 0x2000) {            /* protected */
  125.     kerr(2);
  126.     beep();
  127.     apikberr = sendProtErr;
  128.     return;
  129.     }
  130. if (insmode || inschar) if (cinsert()) {    /* if insert, make room */
  131.         kerr(1);
  132.         beep();        /* error if no room */
  133.         apikberr = sendInsErr;
  134.         return;
  135.         }
  136. newattr = atrbuff[curadr] & 0xbf00; /* update buffer and display */
  137. if (geflag) newattr |= 0x4000;
  138. newchar(curadr, val, newattr, atrbuff[attroff]);
  139. newwrite(0);
  140. atrbuff[attroff] |= 0x0100;        /* set MDT bit */
  141. inpskip = 0;
  142. for (i=0; i < maxcnt; i++) {        /* find next character position */
  143.     curadr++;
  144.     if (curadr == maxcnt) curadr = 0;
  145.     if (atrbuff[curadr] & 0x8000) {
  146.         /* after auto-skip, must find next unprotected field */
  147.         if (inpskip) inpskip = (atrbuff[curadr] & 0x2000) != 0;
  148.                 else inpskip = (atrbuff[curadr] & 0x3000) == 0x3000;
  149.         continue;
  150.         }
  151.     if (inpskip == 0) break;
  152.     }
  153. newcur();
  154. kerr(0);
  155. }
  156.  
  157. attnkey(val)
  158. unsigned char val;
  159. {
  160. short attroff, i;
  161.  
  162. rdaid = val;            /* save aid code for read buffer */
  163.  
  164. if ((val >= 0x6b) && (val <= 0x6e)) {    /* handle short read */
  165.     if (val == 0x6d) {        /* CLEAR erases screen */
  166.         clrscn();
  167.         invldscr();
  168.         }
  169.     if (insmode && cs.insreset) {
  170.         insmode = 0;
  171.         newstat();
  172.         }
  173.     readbuff[0] = 0xd7;
  174.     readbuff[5] = val;
  175.     rbsize = 6;
  176.     if (tcpflg) {
  177.         readbuff[rbsize++] = IAC;
  178.         readbuff[rbsize++] = EOR;
  179.         }
  180.     senddata(0xf6, rbsize-3, readbuff+3, 1);
  181.     return;
  182.     }
  183.  
  184. if (val == 0xf0) {            /* test request read */
  185.     if (insmode && cs.insreset) {
  186.         insmode = 0;
  187.         newstat();
  188.         }
  189.     readbuff[0] = 0xd7;
  190.     readbuff[5] = 0x01;
  191.     readbuff[6] = 0x6c;
  192.     readbuff[7] = 0x61;
  193.     readbuff[8] = 0x02;
  194.     rbsize = 9;
  195.     rdmod(0);        /* append modified data */
  196.     return;
  197.     }
  198.  
  199. if (val == 0x7e) {            /* cursor select */
  200.     if (!fmtscrn) {
  201.         kerr(2);
  202.         beep();
  203.         apikberr = sendAIDErr;
  204.         return;
  205.         }
  206.     attroff = getattr(curadr);
  207.     i = atrbuff[attroff] & 0x0c00;
  208.     if ((i == 0) || (i == 0x0c00)) {
  209.         kerr(2);
  210.         beep();
  211.         apikberr = sendAIDErr;
  212.         return;
  213.         }
  214.     i = attroff + 1;
  215.     if (i == maxcnt) {
  216.         kerr(2);
  217.         beep();
  218.         apikberr = sendAIDErr;
  219.         return;
  220.         }
  221.     switch(chrbuff[i]) {
  222.         case 0x00:            /* space and null */
  223.         case 0x40:    
  224.                 break;
  225.  
  226.         case 0x50:            /* ampersand */
  227.                 val = 0x7d;
  228.                 break;
  229.  
  230.         case 0x6f:            /* question mark */
  231.                 newchar(i, 0x6e, atrbuff[i] & 0xbf00,  
  232.                         atrbuff[attroff]);
  233.                 newwrite(0);
  234.                 atrbuff[attroff] |= 0x0100;    /* set MDT */
  235.                 kerr(0);
  236.                 return;
  237.  
  238.         case 0x6e:            /* greater than */
  239.                 newchar(i, 0x6f, atrbuff[i] & 0xbf00,
  240.                         atrbuff[attroff]);
  241.                 newwrite(0);
  242.                 atrbuff[attroff] &= 0xfeff;    /* reset MDT */
  243.                 kerr(0);
  244.                 return;
  245.  
  246.         default:    
  247.                 kerr(2);
  248.                 beep();
  249.                 apikberr = sendAIDErr;
  250.                 return;
  251.         }
  252.     kerr(0);
  253.     }
  254.  
  255.                     /* normal read-modified */
  256. if (insmode && cs.insreset) {
  257.     insmode = 0;
  258.     newstat();
  259.     }
  260.  
  261. rdmcmd(val);
  262. }
  263.  
  264. rdmcmd(val)                        /* read-modified issued */
  265. unsigned char val;
  266. {
  267. char lp_read;
  268. unsigned char addrbuff[2];
  269. short copylen;
  270.  
  271. lp_read = (val == 0x7e);
  272. readbuff[0] = 0xd7;
  273. readbuff[5] = val;
  274. rbsize = 6;
  275. if ((val == IAC) && tcpflg) {
  276.     readbuff[rbsize++] = IAC;
  277.     }
  278.                         /* append two-byte cursor address */
  279. ebcaddr(addrbuff, curadr);
  280. copylen = 2;
  281. tcpmovmem(addrbuff, readbuff+rbsize, ©len);
  282. rbsize += copylen;        /* append modified data */
  283. rdmod(lp_read);
  284. }
  285.  
  286. rdmacmd(val)                    /* read-modified all issued */
  287. unsigned char val;
  288. {
  289. unsigned char addrbuff[2];
  290. short copylen;
  291.  
  292. readbuff[0] = 0xd7;
  293. readbuff[5] = val;
  294. rbsize = 6;
  295. if ((val == IAC) && tcpflg) {
  296.     readbuff[rbsize++] = IAC;
  297.     }
  298.             /* append two-byte cursor address */
  299. ebcaddr(addrbuff, curadr);
  300. copylen = 2;
  301. tcpmovmem(addrbuff, readbuff+rbsize, ©len);
  302. rbsize += copylen;        /* append modified data */
  303. rdmod(0);
  304. }
  305.  
  306. funckey(val)
  307. unsigned char val;
  308. {
  309. unsigned char t;
  310. register unsigned char prot;
  311. register short a, attroff, b, chroff, i, next;
  312.  
  313. switch(val) {
  314.  
  315. case 1: curadr -= scrhsize;            /* up */
  316.     if (curadr < 0) curadr += maxcnt;
  317.     newcur();
  318.     break;
  319.  
  320. case 2: curadr += scrhsize;            /* down */
  321.     if (curadr > maxoff) curadr -= maxcnt;
  322.     newcur();
  323.     break;
  324.  
  325. case 3: curadr--;                /* left */
  326.     if (curadr < 0) curadr = maxoff;
  327.     newcur();
  328.     break;
  329.  
  330. case 4: curadr++;                /* right */
  331.     if (curadr > maxoff) curadr = 0;
  332.     newcur();
  333.     break;
  334.  
  335. case 5: if (!fmtscrn) {                /* tab */
  336.         curadr = 0;
  337.         newcur();
  338.         return;
  339.         }
  340.     if (atrbuff[curadr] & 0x8000)        /* initial prot value */
  341.         prot = (atrbuff[curadr] & 0x2000) != 0;
  342.     else prot = 1;
  343.     a = curadr + 1;
  344.     if (a == maxcnt) a = 0;        /* loop from next position */
  345.     for (i=0; i < maxcnt; i++) {
  346.         if (atrbuff[a] & 0x8000)
  347.             prot = (atrbuff[a] & 0x2000) != 0;
  348.         else if (!prot) {
  349.             curadr = a;
  350.             newcur();
  351.             return;
  352.             }
  353.         a++;
  354.         if (a == maxcnt) a = 0;
  355.         }
  356.     curadr = 0;
  357.     newcur();
  358.     break;
  359.  
  360. case 6: if (!fmtscrn) {                /* backtab */
  361.         curadr = 0;
  362.         newcur();
  363.         return;
  364.         }
  365.     a = curadr - 1;            /* start at previous position */
  366.     if (a < 0) a = maxoff;
  367.     chroff = -1;            /* no character yet */
  368.     for (i=0; i <= maxcnt; i++) { /* find unprotected character */
  369.         if (atrbuff[a] & 0x8000) {        /* attribute */
  370.             if (atrbuff[a] & 0x2000) chroff = -1;
  371.             else if (chroff > 0) {
  372.                 curadr = chroff;
  373.                 newcur();
  374.                 return;
  375.                 }
  376.             }
  377.         else chroff = a;
  378.         a--;
  379.         if (a < 0) a = maxoff;
  380.         }
  381.     curadr = 0;
  382.     newcur();
  383.     break;
  384.  
  385. case 7: if (!fmtscrn) {                /* newline */
  386.         curadr = ((curadr / scrhsize) + 1) * scrhsize;
  387.         if (curadr == maxcnt) curadr = 0;
  388.         newcur();
  389.         return;
  390.         }
  391.     a = ((curadr / scrhsize) + 1) * scrhsize;
  392.     if (a == maxcnt) a = 0;
  393.     if (!(atrbuff[a] & 0x8000))        /* set prot for first char. */
  394.         prot = (atrbuff[getattr(a)] & 0x2000) != 0;
  395.     for (i=0; i < maxcnt; i++) {
  396.         if (atrbuff[a] & 0x8000) prot = (atrbuff[a] & 0x2000) != 0;
  397.         else if (!prot) {
  398.             curadr = a;
  399.             newcur();
  400.             return;
  401.             }
  402.         a++;
  403.         if (a == maxcnt) a = 0;
  404.         }
  405.     curadr = 0;
  406.     newcur();
  407.     break;
  408.  
  409. case 8: if (!fmtscrn) {                /* home */
  410.         curadr = 0;
  411.         newcur();
  412.         return;
  413.         }
  414.     a = 0;
  415.     if (!(atrbuff[a] & 0x8000))        /* set prot for first char. */
  416.         prot = (atrbuff[getattr(a)] & 0x2000) != 0;
  417.     for (i=0; i < maxcnt; i++) {
  418.         if (atrbuff[a] & 0x8000) prot = (atrbuff[a] & 0x2000) != 0;
  419.         else if (!prot) {
  420.             curadr = a;
  421.             newcur();
  422.             return;
  423.             }
  424.         a++;
  425.         if (a == maxcnt) a = 0;
  426.         }
  427.     curadr = 0;
  428.     newcur();
  429.     break;
  430.  
  431. case 9:                        /* erase eof */
  432.     if (!fmtscrn) {                /* unformatted screen */
  433.         kerr(2);
  434.         beep();
  435.         apikberr = sendFmtErr;
  436.         return;
  437.         }
  438.                         /* else formatted screen */
  439.     if (atrbuff[curadr] & 0x8000) {        /* cursor on attribute byte */
  440.         kerr(2);
  441.         beep();
  442.         apikberr = sendAttrErr;
  443.         return;
  444.         }
  445.     attroff = getattr(curadr);
  446.     if (atrbuff[attroff] & 0x2000) {    /* protected */
  447.         kerr(2);
  448.         beep();
  449.         apikberr = sendProtErr;
  450.         return;
  451.         }
  452.     a = curadr;                /* loop to store nulls */
  453.     for (i=0; i < maxcnt; i++) {
  454.         if (atrbuff[a] & 0x8000) break;        /* stop at attribute */
  455.         newchar(a, 0x00, 0, atrbuff[attroff]);
  456.         a++;
  457.         if (a == maxcnt) a = 0;
  458.         }
  459.     newwrite(0);
  460.     atrbuff[attroff] |= 0x0100;        /* set MDT bit */
  461.     kerr(0);
  462.     break;
  463.  
  464. case 10: if (!fmtscrn) {            /* erase input */
  465.         clrscn();
  466.         invldscr();
  467.         return;
  468.         }
  469.     b = 9999;
  470.     a = firstattr();                /* start at first attribute */
  471.     attroff = 0;
  472.     for (i=0; i < maxcnt; i++) {
  473.         if (atrbuff[a] & 0x8000) {        /* attribute */
  474.             prot = (atrbuff[a] & 0x2000) != 0;
  475.             if (!prot) atrbuff[a] &= 0xfeff;  /* reset MDT */
  476.             attroff = a;        /* save attribute offset */
  477.             }
  478.         else if (!prot) {            /* character */
  479.             newchar(a, 0x00, 0, atrbuff[attroff]);
  480.             if (a < b) b = a;    /* save first character */
  481.             }
  482.         a++;
  483.         if (a == maxcnt) a = 0;
  484.         }
  485.     newwrite(0);
  486.     if (b < 9999) curadr = b;
  487.         else curadr = 0;
  488.     newcur();
  489.     break;
  490.  
  491. case 11: insmode ^= 1;                /* toggle insert mode */
  492.     newstat();
  493.     break;
  494.  
  495. case 12: if (fmtscrn) {                /* delete character */
  496.         if (atrbuff[curadr] & 0x8000) { /* cursor on attribute byte */
  497.             kerr(2);
  498.             beep();
  499.             return;
  500.             }
  501.         i = atrbuff[attroff = getattr(curadr)];
  502.         if (i & 0x2000) {    /* protected */
  503.             kerr(2);
  504.             beep();
  505.             return;
  506.             }
  507.         }
  508.         else i = 0;
  509.     a = curadr;            /* first location to change */
  510.                         /* calculate last location to change */
  511.     if (cs.repnull && fmtscrn) {    
  512.         if (a > 0) b = a - 1;
  513.         else b = maxoff;
  514.         }
  515.     else {
  516.         b = ((curadr / scrhsize) + 1) * scrhsize - 1;    /* last loc. on line */
  517.         }
  518.     while (a != b) {
  519.         next = a+1;
  520.         if (next == maxcnt) next = 0;
  521.         if (atrbuff[next] & 0x8000) break;
  522.         else {
  523.             newchar(a, chrbuff[next], atrbuff[next], i);
  524.             a = next;
  525.             }
  526.         }
  527.     newchar(a, 0x00, 0, i);
  528.     newwrite(0);
  529.     if (fmtscrn) atrbuff[attroff] |= 0x0100;    /* set MDT bit */
  530.     kerr(0);
  531.     break;
  532.  
  533. case 13: kb_err = kblock = kblcode = insmode = 0;    /* reset */
  534.         kbqsize = 0;
  535.         newstat();
  536.         break;
  537.  
  538. case 14: if (!fmtscrn) {            /* dup */
  539.         if (insmode) if (cinsert()) {    /* if insert, make room */
  540.             kerr(1);
  541.             beep();        /* error if no room */
  542.             return;
  543.             }
  544.         b = atrbuff[curadr] & 0xbf00;
  545.         newchar(curadr, 0x1c, b, 0);
  546.         newwrite(0);
  547.         curadr = 0;
  548.         newcur();
  549.         kerr(0);
  550.         return;
  551.         }
  552.                         /* else formatted screen */
  553.     if (atrbuff[curadr] & 0x8000) {        /* cursor on attribute byte */
  554.         kerr(2);
  555.         beep();
  556.         return;
  557.         }
  558.     attroff = getattr(curadr);
  559.     if (atrbuff[attroff] & 0x2000) {            /* protected */
  560.         kerr(2);
  561.         beep();
  562.         return;
  563.         }
  564.     if (insmode) if (cinsert()) {        /* if insert, make room */
  565.             kerr(1);
  566.             beep();        /* error if no room */
  567.             return;
  568.             }
  569.     b = atrbuff[curadr] & 0xbf00;        /* update buffer and display */
  570.     newchar(curadr, 0x1c, b, atrbuff[attroff]);
  571.     newwrite(0);
  572.     atrbuff[attroff] |= 0x0100;        /* set MDT bit */
  573.     kerr(0);
  574.     prot = 1;
  575.     a = curadr + 1;
  576.     if (a == maxcnt) a = 0;        /* loop from next position */
  577.     for (i=0; i < maxcnt; i++) {
  578.         if (atrbuff[a] & 0x8000)
  579.             prot = (atrbuff[a] & 0x2000) != 0;
  580.         else if (!prot) {
  581.             curadr = a;
  582.             newcur();
  583.             return;
  584.             }
  585.         a++;
  586.         if (a == maxcnt) a = 0;
  587.         }
  588.     curadr = 0;
  589.     newcur();
  590.     break;
  591.  
  592. case 15: datakey(0x1e, 0);            /* field mark */
  593.     break;
  594.  
  595. case 16: aplmode ^= 1;                /* toggle APL mode */
  596.     fixbracket = cs.std_brack && (!aplmode) && (stdfont != ALAFONT);
  597.     newstat();
  598.     break;
  599.  
  600. case 17:                            /* insert blank */
  601.     a = curadr;
  602.     inschar = 1;
  603.     datakey(0x40, 0);
  604.     inschar = 0;
  605.     curadr = a;
  606.     newcur();
  607.     break;
  608.  
  609. case 18:                            /* rub out (non-std) */
  610.     a = curadr;                        /* get previous location */
  611.     a--;
  612.     if (a < 0) a = maxoff;
  613.     if (fmtscrn) {
  614.         if (atrbuff[a] & 0x8000) {    /* attribute byte */
  615.             kerr(2);
  616.             beep();
  617.             return;
  618.             }
  619.         attroff = getattr(a);
  620.         if (atrbuff[attroff] & 0x2000) {    /* protected */
  621.             kerr(2);
  622.             beep();
  623.             return;
  624.             }
  625.         }
  626.     curadr = a;
  627.     datakey(0x00, 0);
  628.     curadr = a;
  629.     newcur();
  630.     break;
  631.  
  632. case 19: curadr -= scrhsize * 2;    /* up*2 */
  633.     if (curadr < 0) curadr += maxcnt;
  634.     newcur();
  635.     break;
  636.  
  637. case 20: curadr += scrhsize * 2;    /* down */
  638.     if (curadr > maxoff) curadr -= maxcnt;
  639.     newcur();
  640.     break;
  641.  
  642. case 21: curadr-=2;                /* left */
  643.     if (curadr < 0) curadr += maxcnt;
  644.     newcur();
  645.     break;
  646.  
  647. case 22: curadr+=2;                /* right */
  648.     if (curadr > maxoff) curadr -=maxcnt;
  649.     newcur();
  650.     break;
  651.  
  652. case 23:    cs.curpos ^= 1;        /* cursor position */
  653.             newstat();
  654.             break;
  655.  
  656. default:    
  657.             apikberr = sendOpErr;
  658.             break;
  659.     }
  660.  
  661. }
  662.  
  663. short getattr(offset)
  664. short offset;
  665. {
  666. register short i;
  667. for (i=0; i < maxcnt; i++) {
  668.     if (atrbuff[offset] & 0x8000) return(offset);
  669.     if (offset == 0) offset = maxoff;
  670.         else offset--;
  671.     }
  672. return(offset);
  673. }
  674.  
  675. short firstattr()
  676. {
  677. register short i;
  678. for (i=0; i < maxcnt; i++) {
  679.     if (atrbuff[i] & 0x8000) return(i);
  680.     }
  681.  
  682. return(0);    /* return 0 if no attributes (shouldn't be called this way) */
  683. }
  684.  
  685. rdmod(lp_read)
  686. char lp_read;
  687. {
  688. register unsigned short i, offset, j, k;
  689. register unsigned char c, mod;
  690. char modwrap;        /* true if last modified field may wrap */
  691. unsigned char addrbuff[2];
  692. short copylen;
  693.  
  694. if (cs.repnull) nullreplace();
  695.  
  696. if (!fmtscrn) {
  697.     for (i=0; i < maxcnt; i++) {
  698.         if ((c = chrbuff[i]) == 0) continue;
  699.         if (rbsize > (rballoc-4)) {
  700.             if (tcpflg) {
  701.                 senddata(0xf6, rbsize-3, readbuff+3, 1);
  702.                 rbsize = 5;
  703.                 }
  704.             else {
  705.                 break;
  706.                 }
  707.             }
  708.         if (atrbuff[i] & 0x4000) 
  709.             if (!(((c == 0xad) || (c == 0xbd)) && fixbracket))
  710.                 readbuff[rbsize++] = 0x08;
  711.         readbuff[rbsize++] = c;
  712.         if ((c == IAC) && tcpflg) {
  713.             readbuff[rbsize++] = IAC;
  714.             }
  715.         }
  716.     bufadr = 0;
  717.     if (tcpflg) addeor();
  718.     senddata(0xf6, rbsize-3, readbuff+3, 1);
  719.     return;
  720.     }
  721.  
  722. offset=firstattr();
  723. for (i=0; i < maxcnt; i++) {
  724.     k = atrbuff[offset];
  725.     if (k & 0x8000) {        /* handle attribute byte */
  726.         mod = 0;
  727.         modwrap = 0;
  728.         if (k & 0x0100) {        /* MDT bit set */
  729.             if (!lp_read) {
  730.                 mod = 1;
  731.                 }
  732.             modwrap = 1;
  733.             j = offset+1;
  734.             if (j > maxoff) j = 0;
  735.             if ((rbsize > (rballoc-6)) && tcpflg) {
  736.                 senddata(0xf6, rbsize-3, readbuff+3, 1);
  737.                 rbsize = 5;
  738.                 }
  739.             if (rbsize <= (rballoc-6)) {
  740.                 readbuff[rbsize++] = 0x11;
  741.                 ebcaddr(addrbuff, j);    /* store 2-byte address */
  742.                 copylen = 2;
  743.                 tcpmovmem(addrbuff, readbuff+rbsize, ©len);
  744.                 rbsize += copylen;
  745.                 }
  746.             }
  747.         }
  748.     else if (mod) {            /* handle data byte in modified field */
  749.         if ((c = chrbuff[offset]) != 0) {
  750.             if ((rbsize > (rballoc-4)) && tcpflg) {
  751.                 senddata(0xf6, rbsize-3, readbuff+3, 1);
  752.                 rbsize = 5;
  753.                 }
  754.             if (rbsize <= (rballoc-4)) {
  755.                 if (k & 0x4000) {
  756.                     if (!(((c == 0xad) || (c == 0xbd)) && fixbracket)) {
  757.                         readbuff[rbsize++] = 0x08;
  758.                         }
  759.                     }
  760.                 readbuff[rbsize++] = c;
  761.                 if ((c == IAC) && tcpflg) {
  762.                     readbuff[rbsize++] = IAC;
  763.                     }
  764.                 }
  765.             }
  766.         }
  767.     offset++;
  768.     if (offset > maxoff) offset = 0;
  769.     }
  770. bufadr = 0;
  771. /* change buffer address if last modified field wraps */
  772. if (modwrap && (offset != 0)) bufadr = offset;
  773.  
  774. if (tcpflg) addeor();
  775. senddata(0xf6, rbsize-3, readbuff+3, 1);
  776. }
  777.  
  778. rdbuff()        /* read buffer */
  779. {
  780. register short i;
  781. register unsigned char c, atrbyte;
  782. unsigned char addrbuff[2];
  783. short copylen;
  784.  
  785. readbuff[0] = 0xc2;
  786. readbuff[5] = rdaid;
  787. rbsize = 6;
  788. if ((rdaid == IAC) && tcpflg) {
  789.     readbuff[rbsize++] = IAC;
  790.     }
  791.                         /* append two-byte cursor address */
  792. ebcaddr(addrbuff, curadr);
  793. copylen = 2;
  794. tcpmovmem(addrbuff, readbuff+rbsize, ©len);
  795. rbsize += copylen;
  796.  
  797. if (cs.repnull) nullreplace();
  798.  
  799. for (i=0; i < maxcnt; i++) {
  800.     if (rbsize > (rballoc-4)) {
  801.         if (tcpflg) {
  802.             senddata(0xf2, rbsize-3, readbuff+3, 0);
  803.             rbsize = 5;
  804.             }
  805.         else {
  806.             break;
  807.             }
  808.         }
  809.     if (atrbuff[i] & 0x8000) {    /* attribute byte */
  810.         readbuff[rbsize++] = 0x1d;    /* start field */
  811.         atrbyte = (atrbuff[i] >> 8) & 0x3f;
  812.         readbuff[rbsize++] = ebc64[atrbyte];    /* attribute */
  813.         }
  814.     else {
  815.         c = chrbuff[i];
  816.         if (atrbuff[i] & 0x4000)
  817.             if (!(((c == 0xad) || (c == 0xbd)) && fixbracket))
  818.                 readbuff[rbsize++] = 0x08;
  819.         readbuff[rbsize++] = c;
  820.         if ((c == IAC) && tcpflg) {
  821.             readbuff[rbsize++] = IAC;
  822.             }
  823.         }
  824.     }
  825. bufadr = 0;
  826. if (tcpflg) addeor();
  827. senddata(0xf2, rbsize-3, readbuff+3, 0);
  828. }
  829.  
  830. addeor()
  831. {
  832. if (rbsize > (rballoc-3)) {
  833.     senddata(0xf6, rbsize-3, readbuff+3, 1);
  834.     rbsize = 5;
  835.     }
  836. readbuff[rbsize++] = IAC;
  837. readbuff[rbsize++] = EOR;
  838. }
  839.  
  840. short cinsert()
  841. {
  842. register unsigned char t;
  843. register short a, b, c, i, n;
  844.  
  845. b = c = n = -1;            /* -1 = no blank, character or null found */
  846. a = curadr;            /* scan to end of field or all bytes */
  847. for (i = 0; i < maxcnt; i++) {
  848.     if (atrbuff[a] & 0x8000) break;        /* stop at attribute byte */
  849.     t = chrbuff[a];                /* get charcter value */
  850.                                 /* do null to blank conversion if wanted */
  851.     if ((t == 0x00) && cs.repnull) t = 0x40;
  852.     if (t == 0x00) {            /* found null */
  853.         n = a;                /* remember where */
  854.         break;                /* done now */
  855.         }
  856.     if (t == 0x40) b = i;            /* remember last blank */
  857.     else c = i;                /* remember last character */
  858.     a++;
  859.     if (a == maxcnt) a = 0;
  860.     }
  861.  
  862. if (n >= 0) a = n;            /* use null if found */
  863.     else if ((b > c) && cs.impnull) {    /* else use trailing blank */
  864.         a = curadr + b;                /* (non-standard */
  865.         if (a > maxoff) a -= maxcnt;
  866.         }
  867.         else return(1);        /* else return error */
  868.  
  869. if (fmtscrn) i = atrbuff[getattr(curadr)]; 
  870. else i = 0;
  871. while (a != curadr) {            /* loop to shift bytes right */
  872.     b = a-1;            /* get previous offset */
  873.     if (b < 0) b = maxoff;
  874.     newchar(a, chrbuff[b], atrbuff[b], i); /* define new values */
  875.     a--;
  876.     if (a < 0) a = maxoff;
  877.     }
  878. return(0);
  879. }
  880.  
  881. nullreplace()
  882. {
  883. register unsigned short i, offset, nullcount, a;
  884. register unsigned char mod;
  885. unsigned char *firstnull;
  886.  
  887. if (!fmtscrn) {
  888.     nullcount = 0;
  889.     for (i=0; i < maxcnt; i++) {
  890.         if (chrbuff[i] == 0) {
  891.             if (nullcount == 0) firstnull = chrbuff+offset;
  892.             nullcount++;
  893.             }
  894.         else {
  895.             while (nullcount > 0) {
  896.                 (*firstnull) = 0x40;
  897.                 firstnull++;
  898.                 nullcount--;
  899.                 }
  900.             }
  901.         }
  902.     return;
  903.     }
  904.  
  905. offset=firstattr();
  906. for (i=0; i < maxcnt; i++) {
  907.     a = atrbuff[offset];
  908.     if (a & 0x8000) {        /* handle attribute byte */
  909.         mod = 0;
  910.         if (a & 0x0100) {        /* MDT bit set */
  911.             mod = 1;
  912.             nullcount = 0;
  913.             }
  914.         }
  915.     else if (mod) {            /* handle data byte in modified field */
  916.         if (chrbuff[offset] == 0) {
  917.             if (nullcount == 0) firstnull = chrbuff+offset;
  918.             nullcount++;
  919.             }
  920.         else {
  921.             while (nullcount > 0) {
  922.                 (*firstnull) = 0x40;
  923.                 firstnull++;
  924.                 nullcount--;
  925.                 }
  926.             }
  927.         }
  928.     offset++;
  929.     if (offset > maxoff) offset = 0;
  930.     }
  931. }
  932.  
  933. senddata(code, len, addr, lockflag)
  934. unsigned char code;
  935. short len;
  936. char * addr;
  937. char lockflag;
  938. {
  939. kb_err = 0;
  940. if (tcpflg) {
  941.     if (lockflag) {
  942.         kblock = 1;
  943.         kblcode = 2;
  944.         }
  945.     tcpwrite(readbuff+5, rbsize-5);
  946.     return;
  947.     }
  948. if (serflg == 0) {
  949.     readbuff[3] = NDATA;
  950.     readbuff[4] = code;
  951.     if (lockflag) {
  952.         kblock = 1;
  953.         kblcode = 2;
  954.         }
  955.     atpSndRequest(DATA, rbsize-3, readbuff+3);
  956.     return;
  957.     }
  958. serattn();
  959. if (lockflag) {
  960.     kblock = 1;
  961.     kblcode = 2;
  962.     newstat();
  963.     }
  964. }
  965.  
  966. kerr(code)
  967. short code;
  968. {
  969. if (code == kb_err) return;
  970. kb_err = code;
  971. newstat();
  972. }
  973.  
  974. kbnew(chr, shift)
  975. unsigned char chr, shift;
  976. {
  977. register unsigned char c, typ, val;
  978.  
  979.  
  980. c = chr;                /* get character */
  981.  
  982.             /* define type, value for key */
  983. typ = kbtyp[c] & 0x3f;
  984. if (aplmode) val = kbapl[c];
  985.     else val = kbstd[c];
  986.  
  987.             /* check for Enter or CLEAR to start new session */
  988. if ((typ == 2) && ((val == 0x6d) || (val == 0x7d))) {
  989.     if (serflg) serlgin();
  990.     else if (tcpflg) tcplgin();
  991.     else netlgin();
  992.     return;
  993.     }
  994. beep();
  995. }
  996.  
  997. ebcaddr(buf, addr)
  998. unsigned char *buf;
  999. unsigned short addr;
  1000. {
  1001. if (addr14 && ewamode) {    /* generate 14-bit address */
  1002.     buf[0] = addr/256;
  1003.     buf[0] &= 0x3f;
  1004.     buf[1] = addr%256;
  1005.     }
  1006. else {                        /* generate 12-bit address */
  1007.     buf[0] = ebc64[addr/64];
  1008.     buf[1] = ebc64[addr%64];
  1009.     }
  1010. }
  1011.